<!doctype html><html lang=cn-zh><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="IE=edge"><style type=text/css>body{font-family:monospace}</style><title>SSX，一个有记忆的 ssh 客户端</title>
<meta name=description content="A blog maintained by Vimiix."><link rel=stylesheet href=/css/style.css><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?7c24231917964240bae97e813810620c",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script></head><body><header>====================<br>== Hi, I'm Vimiix ==<br>====================<div style=float:right;color:gray;font-size:x-large>Get hands dirty.</div><br><p><nav><a href=https://www.vimiix.com/><b>首页</b></a>.
<a href=/posts/><b>文章列表</b></a>.
<a href=/projects/><b>开源项目</b></a>.
<a href=/tags/><b>标签</b></a>.
<a href=/friends/><b>友链</b></a>.
<a href=/about/><b>关于我</b></a>.
<a href=/index.xml><b>RSS</b></a>.</nav></p></header><main><article><h1>SSX，一个有记忆的 ssh 客户端</h1><b><time>2023.12.15 00:50</time></b>
<a href=/tags/golang>golang</a>
<a href=/tags/ssx>ssx</a>
<a href=/tags/ssh>ssh</a>
<a href=/tags/tools>tools</a><div><h2 id=需求来源>需求来源</h2><p>对于一个后端程序员来说，在工作中免不了要和繁杂的服务器打交道，ssh 是不可或缺的开发工具。但每次登录都需要输入密码的行为，对于认为一切皆可自动化的程序员来说，肯定是有点繁琐的（如果您是使用图形化界面的用户可忽略）。</p><p>所以我在前段时间考虑，我应该自己实现一个 ssh 客户端，它不需要拥有许多复杂的功能，只需要满足我以下这几个需求即可满足日常使用：</p><ul><li>和 ssh 保持差不多的使用习惯</li><li>仅在第一次登录时询问我密码，后续使用无需再提供密码</li><li>可以给服务器它任意的标签，这样我就可以自由地通过IP 或者标签来登录</li></ul><p>于是乎，近期我在业余时间就设计并编写了 <a href=https://github.com/vimiix/ssx>ssx</a> 这个轻量级的具有记忆的 ssh 客户端。它完美的实现了上面我所需要的功能，也已经被我愉快的应用到了日常的开发中。</p><h2 id=使用方式>使用方式</h2><p>下面就简单介绍一下 ssx 的使用方式。</p><p>ssx 是通过 golang 开发的一个独立的二进制文件，安装方式就是从 <a href=https://github.com/vimiix/ssx/releases>release</a> 页面下载对应平台的软件包，解压后把 ssx 二进制放到系统的任意目录下，这里我习惯放到 <code>/usr/local/bin</code> 目录下，如果你选择其他目录下，需要确保存放的目录添加到 $PATH 环境变量中，这样后续使用我们就不用再添加路径前缀，直接通过 ssx 命令就可以运行了。</p><h3 id=登录服务器>登录服务器</h3><p>使用 ssx 登录服务器的时候，基本和 ssh 使用习惯一致，下面是基本命令模式：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>ssx <span style=color:#f92672>[</span>-s<span style=color:#f92672>]</span> <span style=color:#f92672>[</span>USER@<span style=color:#f92672>]</span>HOST<span style=color:#f92672>[</span>:PORT<span style=color:#f92672>]</span> <span style=color:#f92672>[</span>-k IDENTITY_FILE<span style=color:#f92672>]</span>
</span></span></code></pre></div><p>在这个命令中，<code>USER</code> 是可以省略的，如果省略则是系统当前用户名；<code>PORT</code> 是可以省略的，默认是 22，<code>-k IDENTITY_FILE</code> 代表如果是使用私钥登录，则通过 <code>-k</code> 来指定私钥的路径，也是可以省略的，默认是 <code>~/.ssh/id_rsa</code>，当然了，前提是这个文件存在。所以最精简的登录命令就是：<code>ssx &lt;ip></code></p><p>当首次登录，不存在可用私钥时，会通过交互方式来让用户输入密码，一旦登录成功，这个密码就会被 ssx 保存到本地的数据文件中 (默认为 <code>~/.ssx/db</code>， 可通过环境变量 <code>SSX_DB_PATH</code> 进行自定义)，下次登录时，仍然执行 <code>ssx &lt;ip></code> 即可自动登录。</p><p>注意，登录过的服务器，再次登录时，我嫌输入全部 IP 比较麻烦，所以 ssx 支持输入 IP 中的部分字符，自动搜索匹配进行登录。</p><h3 id=为服务器打标签>为服务器打标签</h3><p>当我们成功登录过一次服务器后，就可以通过 <code>ssx list</code> 命令来查看目前 ssx 存储的所有服务器列表。下面是一个列表示例：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span><span style=color:#75715e># output example</span>
</span></span><span style=display:flex><span><span style=color:#75715e># Entries (stored in ssx)</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#  ID |       Address        |          Tags</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#-----+----------------------+--------------------------</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#  1  | root@172.23.1.84:22  | centos</span>
</span></span></code></pre></div><p>ssx 会给每个服务器分配一个唯一的 ID，我们在打标签时就需要通过 ID 来指定服务器条目。</p><blockquote><p>当然，既然服务器有唯一 ID，ssx 也支持通过 ID 来进行登录：<code>ssx -i &lt;ID></code></p></blockquote><p>打标签需要通过 ssx 的子命令 <code>tag</code> 来完成，下面是 tag 命令的模式：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>ssx tag -i &lt;ENTRY_ID&gt; <span style=color:#f92672>[</span>-t TAG1 <span style=color:#f92672>[</span>-t TAG2 ...<span style=color:#f92672>]]</span> <span style=color:#f92672>[</span>-d TAG3 <span style=color:#f92672>[</span>-d TAG4 ...<span style=color:#f92672>]]</span>
</span></span></code></pre></div><ul><li><code>-i</code> 指定 list 命令输出的要操作的服务器对应的 ID 字段</li><li><code>-t</code> 指定要添加的标签名，可以多次指定就可以同时添加多个标签</li><li><code>-d</code> 指定要删除的标签名，同样也可以多次指定</li></ul><p>当我们完成对服务器的打标签后，比如上面示例中的服务器，我增加了一个 <code>centos</code> 的标签，那么我此时就可以通过标签来进行登录了：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>// -t 可省略
</span></span><span style=display:flex><span>ssx <span style=color:#f92672>[</span>-t<span style=color:#f92672>]</span> centos
</span></span></code></pre></div><h3 id=删除服务器记录>删除服务器记录</h3><p>ssx 也支持删除服务器记录，命令如下：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>ssx delete -i &lt;ID&gt;
</span></span></code></pre></div><p>一旦删除，ssx 不会保留该服务器的任何信息，所以下次登录时会等同于新的服务器来对待，ID 也会重新生成。</p><h3 id=目前支持的环境变量>目前支持的环境变量</h3><p>除了上面提到的 <code>SSX_DB_PATH</code> 可以指定存储数据的文件外，ssx 还支持：</p><ul><li><code>SSX_CONNECT_TIMEOUT</code>：SSH连接超时时间，默认为 <code>10s</code></li><li><code>SSX_IMPORT_SSH_CONFIG</code>：是否引用用户 ssh 配置，默认为空</li></ul><p>这里我解释一下 <code>SSX_IMPORT_SSH_CONFIG</code> 的作用，这个环境变量不设置时，ssx 默认是不会读取用户的 <code>~/.ssh/config</code> 文件的，ssx 只使用自己存储文件进行检索。如果将这个环境变量设置为非空（任意字符串），ssx 就会在初始化的时候加载用户 ssh 配置文件中存在的服务器条目，<strong>但 ssx 仅读取用于检索和登录，并不会将这些条目持久化到 ssx 的存储文件中</strong>，所以，如果 ssx IP 登录时，这个 IP 是 <code>~/.ssh/config</code> 文件中已经配置过登录验证方式的服务器，ssx 匹配到就直接登录了。但 <code>ssx list</code> 查看时，该服务器会被显示到 <code>found in ssh config</code> 的表格中，这个表格中的条目是不具有 ID 属性的，以下是一个示例：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-bash data-lang=bash><span style=display:flex><span>export SSX_IMPORT_SSH_CONFIG<span style=color:#f92672>=</span>true
</span></span><span style=display:flex><span>ssx list
</span></span><span style=display:flex><span><span style=color:#75715e># output example</span>
</span></span><span style=display:flex><span><span style=color:#75715e># Entries (stored in ssx)</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#  ID |       Address        |          Tags</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#-----+----------------------+--------------------------</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#  1  | root@172.23.1.84:22  | centos</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#</span>
</span></span><span style=display:flex><span><span style=color:#75715e># Entries (found in ssh config)</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#               Address              |           Tags</span>
</span></span><span style=display:flex><span><span style=color:#75715e># -----------------------------------+----------------------------</span>
</span></span><span style=display:flex><span><span style=color:#75715e>#   git@ssh.github.com:22            | github.com</span>
</span></span></code></pre></div><h3 id=操作演示>操作演示</h3><p>最后通过一个演示动画来感受一下这个小可爱的功能吧。</p><p><figure><img src="https://raw.githubusercontent.com/vimiix/ssx/master/static/demo.svg?sanitize=true" alt=demo></figure></p></div></article></main><aside><div><div><h3>LATEST POSTS</h3></div><div><ul><li><a href=/posts/2025-10-16-kubernetes-apiserver-authorization-mechanism/>Kubernetes APIServer 鉴权机制</a></li><li><a href=/posts/2025-09-30-kubernetes-apiserver-authentication-mechanism/>Kubernetes APIServer 认证机制</a></li><li><a href=/posts/2024-12-16-deploy-kubernetes-by-kubeadm/>使用 kubeadm 搭建 kubernetes 集群</a></li><li><a href=/posts/2024-09-20-how-to-code-review/>如何做code review</a></li><li><a href=/posts/2024-08-12-weakref-in-python/>Python中的弱引用</a></li></ul></div></div></aside><footer><p>Social Links:
<a href=https://github.com/vimiix><b>Github</b></a>.
<a href=https://www.douban.com/people/vimiix/><b>Douban</b></a>.
<a href=mailto:i@vimiix.com><b>Email</b></a>.<br><hr>&copy; 2017-2025
Vimiix Yao; All rights reserved.
<a href=https://beian.miit.gov.cn/>京ICP备19015214号-1</a></p><script src=https://l2dwidget.js.org/lib/L2Dwidget.min.js></script><script>L2Dwidget.init({model:{jsonPath:"https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json"}})</script></footer></body></html>